package datapack

import (
	"broker/interface/imodel"
	"broker/struct/model"
	"bytes"
	"encoding/binary"
	"errors"
)

type ParamDataPack struct {
	dataPackMsg []byte
	paramIndex  uint32
}

func NewParamDataPack(dataPackMsg []byte) *ParamDataPack {
	return &ParamDataPack{
		paramIndex:  0,
		dataPackMsg: dataPackMsg,
	}
}

func (pd *ParamDataPack) Pack(data []byte) []byte {
	len := len(data)
	lenList := make([]byte, 2)
	binary.BigEndian.PutUint16(lenList, uint16(len))
	return append(lenList, data...)
}
func (pd *ParamDataPack) UnPack() (imodel.IParamData, error) {

	dataBuff := bytes.NewBuffer(pd.dataPackMsg[pd.paramIndex:])
	if dataBuff.Len() == 0 {
		return nil, errors.New("no data")
	}
	//读取参数长度
	var dataLen uint16
	if err := binary.Read(dataBuff, binary.BigEndian, &dataLen); err != nil {
		return nil, err
	}
	paramData := model.NewParamData()
	paramData.SetDataLen(uint32(dataLen))
	//读取参数
	data := make([]byte, dataLen)
	if err := binary.Read(dataBuff, binary.BigEndian, &data); err != nil {
		return nil, err
	}
	paramData.SetData(data)
	pd.paramIndex += 2 + paramData.GetDataLen()
	return paramData, nil
}

func (pd *ParamDataPack) UnPackByLen(dataLen uint32) (imodel.IParamData, error) {

	dataBuff := bytes.NewBuffer(pd.dataPackMsg[pd.paramIndex:])
	if dataBuff.Len() == 0 {
		return nil, errors.New("no data")
	}
	paramData := model.NewParamData()
	paramData.SetDataLen(dataLen)
	data := make([]byte, dataLen)
	if err := binary.Read(dataBuff, binary.BigEndian, &data); err != nil {
		return nil, err
	}
	paramData.SetData(data)
	pd.paramIndex += dataLen
	return paramData, nil
}

func (pd *ParamDataPack) GetDataPackMsg() []byte {
	return pd.dataPackMsg
}
func (pd *ParamDataPack) UnPackAll() (imodel.IParamData, error) {
	dataBuff := bytes.NewBuffer(pd.dataPackMsg[pd.paramIndex:])
	paramData := model.NewParamData()
	paramData.SetDataLen(uint32(dataBuff.Len()))
	paramData.SetData(dataBuff.Bytes())
	pd.paramIndex += paramData.GetDataLen()
	return paramData, nil
}
